/* 
 * File:   mc_t.cpp
 * Author: alfredolp
 *
 * Version Thread
 */

#include <stdio.h>
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
#include <gmpxx.h> 

#define MAX 2 // Numero maximo de Threads

int ret;
double dRand(double lower, double upper);
void *monte_carlo(void *n_total);

using namespace std;

int main() {
    pthread_t threads[MAX];
    int n = 2147483640/MAX;
    //int n = 10000000/MAX;
    int *p_in[MAX]; 
    int p_in_sum = 0;
    int p_total = 0;
    double result = .0;
    //mpz_class p_in_sum = 0;
    //mpz_class p_total = 0;
    //mpf_class result = .0f;


    for(int i=0; i<MAX; i++) {
        pthread_create( &(threads[i]), NULL, monte_carlo, &n ); 
    }
    
    for(int i=0; i<MAX; i++) {
        pthread_join( threads[i], (void**)&p_in[i] );
    }

    for(int i=0; i<MAX; i++) {
        p_in_sum += (*p_in[i]);
        p_total += n;
    }

    cout << p_in_sum << endl;
    cout << p_total << endl;

    //mpf_set_default_prec(1024);
    //result.set_prec(1024);

    //result = ( (mpf_class) p_in_sum ) / ( (mpf_class) p_total );
    result = ((double)p_in_sum/p_total);  

    result *= 4.0;
    
    //cout.precision(11000);
    cout << result << endl;

    return 0;
}


void *monte_carlo( void *n_total ) {
    int i, *p_total = (int*) n_total;

    int *p_in = (int*) malloc (sizeof(int));
    *p_in = 0;

    double px, py;

    srand (time(NULL));
    
    for (i = 0; i < *p_total; i++) {
        // gera um numero aleatorio double  0 entre 1, para cordenada x e y do ponto p
        px = drand48();
        py = drand48();

        //printf("%lf %lf\n", px, py);        

        // verifica se o ponto da dentro, ou fora do 1/4 circulo
        if ( ((px*px)+(py*py))  <= 1.0 ) (*p_in)++;
    }

    // retorna o valor de p_in no join
    pthread_exit( p_in );

    return (void*)p_in;
}
